package yxk.report.wtc.wtte;

import com.google.common.collect.Maps;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.events.BizDataEventArgs;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.property.BasedataProp;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.exception.KDBizException;
import kd.bos.form.IFormView;
import kd.bos.form.control.Control;
import kd.bos.form.control.events.RefreshNodeEvent;
import kd.bos.form.control.events.TreeNodeEvent;
import kd.bos.form.events.BeforeBuildTreeNodeEvent;
import kd.bos.form.events.BeforeTreeNodeClickEvent;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.MulBasedataEdit;
import kd.bos.form.field.events.BeforeF7SelectEvent;
import kd.bos.form.field.events.BeforeF7SelectListener;
import kd.bos.list.ListShowParameter;
import kd.bos.list.events.BuildTreeListFilterEvent;
import kd.bos.list.plugin.ITreeListPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.report.plugin.AbstractReportFormPlugin;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.util.StringUtils;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.hr.hbp.common.util.HRDateTimeUtils;
import kd.hr.hbp.common.util.HRStringUtils;
import kd.sdk.plugin.Plugin;
import kd.wtc.wtbs.business.history.service.WTCHisServiceHelper;
import kd.wtc.wtbs.common.helper.WTCAppContextHelper;
import kd.wtc.wtbs.common.util.WTCCollections;
import kd.wtc.wtte.business.attreport.AttReportService;
import kd.wtc.wtte.business.viewcalsteps.AttRecordUtils;
import kd.wtc.wtte.common.enums.AttrecordPromptEnum;
import kd.wtc.wtte.formplugin.web.report.RecordSumDayListRFPlugin;
import yxk.utils.DateUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 考勤数据查询表
 * 工时假勤云-考勤核算-考勤记录汇总
 * 报表表单插件
 */
public class AttFilesDataReportPlugin extends AbstractReportFormPlugin implements Plugin, BeforeF7SelectListener {

    @Override
    public void beforeBindData(EventObject e) {

    }

    @Override
    public void registerListener(EventObject e) {
       /* MulBasedataEdit mEdit = this.getView().getControl("con_adminorg");
        MulBasedataEdit mEditOrg = this.getView().getControl("con_affiliateadminorg");
        mEdit.addBeforeF7SelectListener(this);
        mEditOrg.addBeforeF7SelectListener(this);
        MulBasedataEdit attPer = this.getView().getControl("attperinf");
        attPer.addBeforeF7SelectListener(this);*/

    }
    @Override
    public void beforeF7Select(BeforeF7SelectEvent event) {
        String fieldKey = event.getProperty().getName();
        long currentUserId = UserServiceHelper.getCurrentUserId();
        ArrayList<Long> ids = new ArrayList<>();
        ids.add(currentUserId);
        Map<Long, Long> userIds = UserServiceHelper.getCompanyByUserIds(ids);
        Long orgID = userIds.get(currentUserId);
        QFilter qf=null;
        switch (fieldKey){
            case "con_adminorg":
            case "con_affiliateadminorg":
            case "attperinf":
                qf=new QFilter("company", QCP.equals,orgID);
            break;
        }
        ListShowParameter showParameter = (ListShowParameter) event.getFormShowParameter();
        showParameter.getListFilterParameter().setFilter(qf);
    }

    public void beforeQuery(ReportQueryParam queryParam) {
        super.beforeQuery(queryParam);

        DynamicObject entity = this.getModel().getDataEntity();
        DynamicObject org = entity.getDynamicObject("con_org");
        if(org == null){
            throw new KDBizException(ResManager.loadKDString("“考勤管理组织”必填。", "AttFilesDataReportPlugin_1", "yxk.report.wtc.wtte", new Object[0]));
        }
        Date owndatestart = entity.getDate("owndatestart");
        Date owndateend = entity.getDate("owndateend");
        if(owndatestart == null || owndateend == null){
            throw new KDBizException(ResManager.loadKDString("“归属日期”必填。", "AttFilesDataReportPlugin_1", "yxk.report.wtc.wtte", new Object[0]));
        }

        DynamicObject showPlanDy = this.getShowPlanDy();
        DynamicObjectCollection displayEntryDys = showPlanDy.getDynamicObjectCollection("displayentryentity");
        DynamicObject[] showFieldDys = this.queryDisplayFieldData(displayEntryDys, "fieldvalue");

        LinkedHashMap<String, Object> displayMap = Maps.newLinkedHashMapWithExpectedSize(displayEntryDys.size());

        this.genShowFieldColumns(displayEntryDys, showFieldDys, displayMap);
        String mulcom = entity.getString("mulcom");
        if(mulcom != null) {
            String[] split = mulcom.split(",");
            this.getFieldColumnsDay(split, owndatestart, owndateend, displayMap);
        }
        queryParam.setCustomParam(displayMap);
    }

    private void getFieldColumnsDay(String[] split,Date start,Date end,LinkedHashMap<String, Object> displayMap){

        Date day=start;
        Calendar instance = Calendar.getInstance();
        instance.setTime(end);
        instance.add(Calendar.DATE,1);
        while (day.before(instance.getTime())){

            for (int i = 1; i < split.length; i++) {
                String name="";
                String fieidType="";
                String s = split[i];
                String number = day.getTime() + s+"_";
                String tidying="";
                switch (s){
                    case "1":
                        name="原始卡点";
                        tidying="ffrees";
                        fieidType="text";
                        break;
                    case "2":
                        name="有效卡点";
                        tidying="feffectives";
                        fieidType="text";
                        break;
                    case "3":
                        name="班次";
                        tidying="fshift";
                        fieidType="text";
                        break;
                    case "4":
                        name="实际出勤时长";
                        tidying="freality";
                        fieidType="decimal";
                        break;
                    case "5":
                        name="原始出勤时长";
                        tidying="forigin";
                        fieidType="decimal";
                        break;
                    case "6":
                        name="考勤结果";
                        tidying="fresults";
                        fieidType="text";
                        break;
                }
                Map<String, Object> custom = this.getColumnMap(false, fieidType, false, "custom", number, name, false, tidying,String.valueOf(day.getTime()));
                displayMap.put(UUID.randomUUID().toString(),custom);
            }
            Calendar cld=Calendar.getInstance();
            cld.setTime(day);
            cld.add(Calendar.DATE,1);
            day=cld.getTime();

        }
    }
    private void genShowFieldColumns(DynamicObjectCollection displayEntryDys, DynamicObject[] showFieldDys, LinkedHashMap<String, Object> displayMap) {
        HRBaseServiceHelper helper = new HRBaseServiceHelper("wtbd_attitem");
        QFilter qFilter = WTCHisServiceHelper.statusValidQFilter().and(WTCHisServiceHelper.dataStatusValidQFilter()).and(WTCHisServiceHelper.isCurrentVersion(true));
        DynamicObject[] attItemDys = helper.queryOriginalArray("id, boid, number, name", new QFilter[]{qFilter});
        Map<Long, String> attItemMap = new HashMap<>();
        Set<Long> attItemBoIds =new HashSet<>();
        for (DynamicObject attItemDy : attItemDys) {
            attItemMap.put(attItemDy.getLong("id"),attItemDy.getString("name"));
            attItemBoIds.add(attItemDy.getLong("boid"));
        }
        Iterator var10 = displayEntryDys.iterator();

        while(var10.hasNext()) {
            DynamicObject displayEntryDy = (DynamicObject)var10.next();
            long fieldValueId = Long.parseLong(displayEntryDy.getString("fieldvalue"));
            boolean freeze = displayEntryDy.getBoolean("freeze");
            String displayName = displayEntryDy.getString("displayname");
            if (displayName == null || displayName.isEmpty()) {
                displayName = displayEntryDy.getString("fieldname");
            }

            if (attItemBoIds.contains(fieldValueId)) {
                boolean flag = true;
                if (!displayName.contains("/")) {
                    String fieldName = displayEntryDy.getString("fieldname");
                    displayName = displayName + fieldName.substring(fieldName.lastIndexOf(47));
                    flag = false;
                }

                int indexOf = displayName.lastIndexOf(47);
                String name = displayName.substring(0, indexOf);
                if (flag) {
                    String tempName = (String)attItemMap.get(fieldValueId);
                    if (HRStringUtils.isNotEmpty(tempName)) {
                        name = tempName;
                    }
                }

                Map<String, Object> map = this.getColumnMap(freeze, "decimal", true, "attiem", AttReportService.attIdApp(fieldValueId), name, false, (String)null,null);
                displayMap.put(String.valueOf(fieldValueId), map);
            } else {
                this.genNotAttItemColumn(showFieldDys, displayMap, fieldValueId, freeze, displayName);
           }
        }

    }

    public void propertyChanged(PropertyChangedArgs propertyChangedArgs) {
        super.propertyChanged(propertyChangedArgs);
        String name = propertyChangedArgs.getProperty().getName();
        AttRecordUtils.clearViewKey(name, this.getModel());
        switch (name) {
            case "owndatestart":
                checkQwndate("owndatestart", "owndateend", this.getView(), name);
                break;
            case "owndateend":
                checkQwndate("owndatestart", "owndateend", this.getView(), name);
        }

    }

    public static boolean checkQwndate(String beginDateKer, String endDateKer, IFormView view, String changeKey) {
        if (!HRStringUtils.isEmpty(beginDateKer) && !HRStringUtils.isEmpty(endDateKer) && view != null) {
            IDataModel model = view.getModel();
            Date beginDate = model.getDataEntity().getDate(beginDateKer);
            Date endDate = model.getDataEntity().getDate(endDateKer);
            if (beginDate != null && endDate != null) {
                int addMonth = 1;

                Date date = addMonth(beginDate, addMonth);
                if (!endDate.before(date)) {
                    model.setValue(changeKey, (Object)null);
                    view.showTipNotification(AttrecordPromptEnum.DATE_ACROSS_ONE.load());
                    return false;
                } else {
                    return true;
                }
            } else {
                return true;
            }
        } else {
            return true;
        }
    }

    public static Date addMonth(Date dDate, int iNbMonth) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dDate);
        int month = cal.get(2);
        month += iNbMonth;
        int year = month / 12;
        month %= 12;
        cal.set(2, month);
        cal.set(Calendar.DATE,cal.get(Calendar.DATE)+1);
        if (year != 0) {
            int oldYear = cal.get(1);
            cal.set(1, year + oldYear);
        }

        return cal.getTime();
    }

    private DynamicObject getShowPlanDy() {
        DynamicObject dynamicObject = this.getModel().getDataEntity().getDynamicObject("con_showplan");
        if (dynamicObject == null) {
            throw new KDBizException(ResManager.loadKDString("“显示方案”必填。", "RecordReportBaseFormPlugin_1", "wtc-wtte-formplugin", new Object[0]));
        } else {
            Object pkValue = dynamicObject.getPkValue();
            HRBaseServiceHelper helper = new HRBaseServiceHelper("wtte_dailydetscheme");
            return helper.loadDynamicObject(new QFilter("id", "=", pkValue));
        }
    }

    private DynamicObject[] queryDisplayFieldData(DynamicObjectCollection displayEntryDys, String propertyName) {
        List<Long> ids=new ArrayList<>();
        for (DynamicObject displayEntryDy : displayEntryDys) {
            String source = displayEntryDy.getString("fieldsource");
            if(!"考勤记录".equals(source)){
                long aLong = displayEntryDy.getLong(propertyName);
                ids.add(aLong);
            }
        }
        HRBaseServiceHelper helper = new HRBaseServiceHelper("wtte_fieldscheme");
        DynamicObject[] dynamicObjects = helper.queryOriginalArray("id, longnumber, parent.number, number, datasource", new QFilter[]{new QFilter("id", "in", ids)});
        return dynamicObjects;
    }

    /**
     *
     * @param freeze            --冻结列
     * @param fieldType         --字段类型
     * @param isHyperLink       --设置为超链接
     * @param fieldSourceType   --归类
     * @param number            --标识
     * @param displayName       --字段名称
     * @param isHide            --是否隐藏
     * @param sortType
     * @return
     */
    private Map<String, Object> getColumnMap(boolean freeze, String fieldType, boolean isHyperLink, String fieldSourceType, String number, String displayName, boolean isHide, String sortType,String time) {
        Map<String, Object> map = Maps.newHashMapWithExpectedSize(16);
        map.put("name", displayName);
        map.put("number", number);
        map.put("fieldtype", fieldType);
        map.put("ishyperlink", isHyperLink);
        map.put("fieldSourceType", fieldSourceType);
        map.put("freeze", freeze);
        map.put("isHide", isHide);
        map.put("sorttype", sortType);
        map.put("time", time);
        return map;
    }
    private void genNotAttItemColumn(DynamicObject[] fieldDys, LinkedHashMap<String, Object> displayMap, long fieldValueId, boolean freeze, String displayName) {
        DynamicObject[] var9 = fieldDys;
        int var10 = fieldDys.length;

        for(int var11 = 0; var11 < var10; ++var11) {
            DynamicObject fieldDy = var9[var11];
            if (fieldValueId == fieldDy.getLong("id")) {
                String dataSource = fieldDy.getString("datasource");
                String longNumber = fieldDy.getString("longnumber");
                String fieldType = this.getFieldType(dataSource, fieldDy.getString("number"));
                String fieldSourceType = "normal";
                Map<String, Object> map = this.getColumnMap(freeze, fieldType, false, fieldSourceType, longNumber, displayName, false, (String)null,null);
                displayMap.put(String.valueOf(fieldValueId), map);
            }
        }

    }

    private String getFieldType(String dataSource, String fieldNumber) {
        if (HRStringUtils.isEmpty(dataSource)) {
            return "text";
        } else {
            MainEntityType mainEntityType = MetadataServiceHelper.getDataEntityType(dataSource);
            return mainEntityType == null ? "text" : this.spliteFieldNumberType(fieldNumber, mainEntityType);
        }
    }

    private String spliteFieldNumberType(String fieldNumber, MainEntityType mainEntityType) {
        if (HRStringUtils.isEmpty(fieldNumber)) {
            return "text";
        } else {
            String[] fieldList = fieldNumber.split("\\.");
            if (fieldList != null && fieldList.length != 0) {
                String spliteFileldType;
                if (fieldList.length > 1) {
                    if (mainEntityType == null) {
                        return "text";
                    }

                    IDataEntityProperty iDataEntityProperty = (IDataEntityProperty)mainEntityType.getProperties().stream().filter((ob) -> {
                        return HRStringUtils.equals(ob.getName(), fieldList[0]);
                    }).findFirst().orElse(null);
                    if (iDataEntityProperty == null) {
                        return "text";
                    }

                    if (iDataEntityProperty instanceof BasedataProp) {
                        mainEntityType = MetadataServiceHelper.getDataEntityType(((BasedataProp)iDataEntityProperty).getBaseEntityId());
                    }

                    fieldNumber = fieldNumber.substring(fieldNumber.indexOf(46) + 1);
                    spliteFileldType = this.spliteFieldNumberType(fieldNumber, mainEntityType);
                } else {
                    spliteFileldType = this.changeFieldType(mainEntityType, fieldNumber);
                }

                return spliteFileldType;
            } else {
                return "text";
            }
        }
    }

    private String changeFieldType(MainEntityType mainEntityType, String fieldNumber) {
        DataEntityPropertyCollection dataEntityPropertyCollection = mainEntityType.getProperties();
        if (WTCCollections.isEmpty(dataEntityPropertyCollection)) {
            return "text";
        } else {
            Iterator var4 = dataEntityPropertyCollection.iterator();

            IDataEntityProperty iDataEntityProperty;
            do {
                if (!var4.hasNext()) {
                    return "text";
                }

                iDataEntityProperty = (IDataEntityProperty)var4.next();
            } while(!HRStringUtils.equals(iDataEntityProperty.getName(), fieldNumber));

            Class propertyType = iDataEntityProperty.getPropertyType();
            if (propertyType == null) {
                return "text";
            } else {
                String name = propertyType.getName();
                if (HRStringUtils.equals(name, "java.lang.String")) {
                    return "text";
                } else if (HRStringUtils.equals(name, "java.math.BigDecimal")) {
                    return "decimal";
                } else if (!HRStringUtils.equals(name, "java.lang.Long") && !HRStringUtils.equals(name, "java.lang.Integer")) {
                    if (HRStringUtils.equals(name, "java.util.Date")) {
                        return "date";
                    } else if (!HRStringUtils.equals(name, "java.lang.Boolean") && !HRStringUtils.equals(name, "boolean")) {
                        return "text";
                    } else {
                        return "checkbox";
                    }
                } else {
                    return "integer";
                }
            }
        }
    }

    private List<String> getDisplayFiledNumberList(LinkedHashMap<String, Object> displayMap) {
        List<String> numberList = new ArrayList(displayMap.size());
        Iterator var3 = displayMap.values().iterator();

        while(var3.hasNext()) {
            Object map = var3.next();
            Map<String, Object> currentMap = (Map)map;
            if (!"sorttype".equals(String.valueOf(currentMap.get("fieldSourceType")))) {
                numberList.add(String.valueOf(currentMap.get("number")));
            }
        }

        return numberList;
    }

}